package com.ruoyi.common.core.utils.uuid;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

/**
 * ID生成器工具类
 * 
 * @author ruoyi
 */
public class IdUtils
{
    /**
     * 获取随机UUID
     * 
     * @return 随机UUID
     */
    public static String randomUUID()
    {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String simpleUUID()
    {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 随机UUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String fastSimpleUUID()
    {
        return UUID.fastUUID().toString(true);
    }

    /**
     * 将UUID转换为指定长度的long类型ID
     * @param uuid UUID字符串
     * @param length 期望的long ID长度
     * @return 指定长度的long类型ID
     */
    public static long uuidToLong(String uuid, int length) {
        // 获取UUID的哈希码
        int hashCode = uuid.hashCode();
        // 生成指定长度的掩码，掩码大小为10^length - 1
        long mask = (long) Math.pow(10, length) - 1;
        // 使用掩码获取指定长度的ID
        return Math.abs(hashCode) % mask;
    }

    // 保存longId到UUID的映射关系
    private static final Map<Long, String> longIdToUuidMap = new HashMap<>();

    /**
     * 将UUID转换为指定长度的long类型ID
     * @param uuidStr UUID字符串
     * @param length 期望的long ID长度（1-19位）
     * @return 指定长度的long类型ID
     */
    public static long uuidToLongId(String uuidStr, int length) {
        UUID uuid = parseUUID(uuidStr);
        ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
        byteBuffer.putLong(uuid.getMostSignificantBits());
        byteBuffer.putLong(uuid.getLeastSignificantBits());
        long value = byteBuffer.getLong(0) ^ byteBuffer.getLong(8); // 简单的XOR操作获取混合值
        long mask = (long) Math.pow(10, length) - 1;
        long longId = Math.abs(value) % mask;

        // 保存longId到UUID的映射关系
        longIdToUuidMap.put(longId, uuidStr);

        return longId;
    }

    /**
     * 将指定长度的long ID转换回UUID字符串
     * @param longId long ID
     * @param length 期望的long ID长度
     * @return UUID字符串
     */
    public static String longIdToUuid(long longId, int length) {
        // 通过longId从映射关系中获取原始UUID
        String originalUuidStr = longIdToUuidMap.get(longId);
        if (originalUuidStr == null) {
            throw new IllegalArgumentException("Invalid long ID: " + longId);
        }
        return originalUuidStr;
    }

    /**
     * 将非标准格式的UUID字符串解析为UUID对象
     * @param uuidStr 非标准格式的UUID字符串
     * @return UUID对象
     */
    private static UUID parseUUID(String uuidStr) {
        if (uuidStr.length() == 32) {
            return UUID.fromString(uuidStr.replaceFirst(
                    "(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})",
                    "$1-$2-$3-$4-$5"));
        } else {
            throw new IllegalArgumentException("Invalid UUID string: " + uuidStr);
        }
    }
}
